import { Vec3 } from '@/core/types';
import { BlockType } from '@/blocks/types';
import { WorldManager } from '@/world/WorldManager';

export interface MechanicalDevice {
  position: Vec3;
  type: string;
  isActive: boolean;
  lastUpdate: number;
}

export class RedstoneMechanics {
  private worldManager: WorldManager;
  private devices: Map<string, MechanicalDevice> = new Map();

  constructor(worldManager: WorldManager) {
    this.worldManager = worldManager;
  }

  public addDevice(position: Vec3, type: string): void {
    const key = this.getPositionKey(position);
    const device: MechanicalDevice = {
      position: { ...position },
      type,
      isActive: false,
      lastUpdate: Date.now()
    };

    this.devices.set(key, device);
  }

  public removeDevice(position: Vec3): void {
    const key = this.getPositionKey(position);
    this.devices.delete(key);
  }

  public activateDevice(position: Vec3, powerLevel: number): void {
    const key = this.getPositionKey(position);
    const device = this.devices.get(key);

    if (device && powerLevel > 0 && !device.isActive) {
      device.isActive = true;
      device.lastUpdate = Date.now();
      this.executeDeviceAction(device);
    } else if (device && powerLevel === 0 && device.isActive) {
      device.isActive = false;
      device.lastUpdate = Date.now();
      this.deactivateDeviceAction(device);
    }
  }

  private executeDeviceAction(device: MechanicalDevice): void {
    switch (device.type) {
      case 'piston':
        this.activatePiston(device.position);
        break;
      case 'door':
        this.openDoor(device.position);
        break;
      case 'dispenser':
        this.activateDispenser(device.position);
        break;
      default:
        console.log(`Unknown device type: ${device.type}`);
    }
  }

  private deactivateDeviceAction(device: MechanicalDevice): void {
    switch (device.type) {
      case 'piston':
        this.retractPiston(device.position);
        break;
      case 'door':
        this.closeDoor(device.position);
        break;
    }
  }

  private activatePiston(position: Vec3): void {
    console.log(`Piston at (${position.x}, ${position.y}, ${position.z}) extending`);
    
    // 简化的活塞逻辑：推动前方的方块
    const frontPosition = {
      x: position.x,
      y: position.y,
      z: position.z - 1 // 假设活塞朝北
    };

    const blockInFront = this.worldManager.getBlock(frontPosition);
    if (blockInFront !== BlockType.AIR) {
      // 尝试推动方块
      const pushToPosition = {
        x: frontPosition.x,
        y: frontPosition.y,
        z: frontPosition.z - 1
      };

      const blockAtPushPosition = this.worldManager.getBlock(pushToPosition);
      if (blockAtPushPosition === BlockType.AIR) {
        // 移动方块
        this.worldManager.setBlock(pushToPosition, blockInFront);
        this.worldManager.setBlock(frontPosition, BlockType.AIR);
        console.log(`Piston pushed block from (${frontPosition.x}, ${frontPosition.y}, ${frontPosition.z}) to (${pushToPosition.x}, ${pushToPosition.y}, ${pushToPosition.z})`);
      } else {
        console.log(`Piston cannot push - block in the way`);
      }
    }
  }

  private retractPiston(position: Vec3): void {
    console.log(`Piston at (${position.x}, ${position.y}, ${position.z}) retracting`);
    // 活塞收回逻辑（简化版）
  }

  private openDoor(position: Vec3): void {
    console.log(`Door at (${position.x}, ${position.y}, ${position.z}) opening`);
    
    // 简化的门逻辑：移除门方块
    this.worldManager.setBlock(position, BlockType.AIR);
  }

  private closeDoor(position: Vec3): void {
    console.log(`Door at (${position.x}, ${position.y}, ${position.z}) closing`);
    
    // 简化的门逻辑：放置门方块（这里用木板代替）
    this.worldManager.setBlock(position, BlockType.PLANKS);
  }

  private activateDispenser(position: Vec3): void {
    console.log(`Dispenser at (${position.x}, ${position.y}, ${position.z}) dispensing item`);
    
    // 简化的发射器逻辑：在前方生成一个方块
    const frontPosition = {
      x: position.x,
      y: position.y,
      z: position.z - 1
    };

    if (this.worldManager.getBlock(frontPosition) === BlockType.AIR) {
      this.worldManager.setBlock(frontPosition, BlockType.STONE);
      console.log(`Dispenser placed stone at (${frontPosition.x}, ${frontPosition.y}, ${frontPosition.z})`);
    }
  }

  public update(deltaTime: number): void {
    // 更新所有机械装置的状态
    for (const device of this.devices.values()) {
      // 这里可以添加设备的持续效果或动画
      if (device.isActive && device.type === 'piston') {
        // 活塞的持续推力效果等
      }
    }
  }

  private getPositionKey(position: Vec3): string {
    return `${Math.floor(position.x)},${Math.floor(position.y)},${Math.floor(position.z)}`;
  }

  public getDeviceCount(): number {
    return this.devices.size;
  }

  public getActiveDeviceCount(): number {
    return Array.from(this.devices.values()).filter(device => device.isActive).length;
  }

  public clear(): void {
    this.devices.clear();
  }

  public getDebugInfo(): any {
    return {
      totalDevices: this.devices.size,
      activeDevices: this.getActiveDeviceCount(),
      deviceTypes: this.getDeviceTypeCount()
    };
  }

  private getDeviceTypeCount(): Record<string, number> {
    const counts: Record<string, number> = {};
    for (const device of this.devices.values()) {
      counts[device.type] = (counts[device.type] || 0) + 1;
    }
    return counts;
  }
}